import fs from 'fs'; import path from 'path';
import Yaml from 'yaml';

export const PLUGIN_PATH = path.join(path.resolve(), 'plugins', 'Slave-Market');
const FILE_PATH = {
    player: path.join(PLUGIN_PATH, 'data', 'player')
};

// 新增：读取配置文件的函数
export function getConfig() {
    const config = Yaml.parse(fs.readFileSync(path.join('config', 'SlaveMarket_config.yaml'), 'utf8'));
    // 将配置中的ID转换为字符串以便比较
    config.ignoreCDUsers = (config.ignoreCDUsers || []).map(String);
    return config;
}

/** 读取玩家数据 */
export async function getPlayerData(GROUP_ID, ID) {
    const DATA = await JSON.parse(fs.readFileSync(path.join(FILE_PATH['player'], GROUP_ID.toString(), ID + '.json'), 'utf8'))
    return DATA
}

/** 存储玩家数据 */
const locks = new Map();
export async function storagePlayerData(GROUP_ID, ID, DATA, nickname = '') {
    const filePath = path.join(FILE_PATH['player'], GROUP_ID.toString(), ID + '.json');

    while (locks.get(filePath)) {
        await new Promise(resolve => setTimeout(resolve, 10)); // 每 10ms 检查一次
    }

    locks.set(filePath, true);

    try {
        if (DATA.slave) {
            DATA.slave = [...new Set(DATA.slave.map(Number))];
        }

        // 更新昵称
        if (nickname && (!DATA.nickname || DATA.nickname !== nickname)) {
            DATA.nickname = nickname;
        }

        fs.writeFileSync(filePath, JSON.stringify(DATA, null, 4));
    } finally {
        locks.delete(filePath);
    }
}

/** 判断玩家是否存在 */
export function isPlayerExist(GROUP_ID, ID) {
    if (fs.existsSync(path.join(FILE_PATH['player'], GROUP_ID.toString(), ID + '.json'))) {
        return true
    }
    return false
}

/** 判断群是否存在 */
export function isGroupExist(GROUP_ID) {
    if (fs.existsSync(path.join(FILE_PATH['player'], GROUP_ID.toString().toString()))) {
        return true
    }
    return false
}

/** 创建群文件夹 */
export function createAGroupFolder(GROUP_ID) {
    fs.mkdirSync(path.join(FILE_PATH['player'], GROUP_ID.toString()), { recursive: true })
}

/** 读取群文件夹用户列表 */
export function getGroupPlayerList(GROUP_ID) {
    return fs.readdirSync(path.join(FILE_PATH['player'], GROUP_ID.toString()))
}

/** 删除玩家数据 */
export function deletePlayerData(GROUP_ID, ID) {
    const filePath = path.join(FILE_PATH['player'], GROUP_ID.toString(), ID + '.json');

    if (!fs.existsSync(filePath)) {
        logger.warn(`尝试删除不存在的存档: 群${GROUP_ID} 用户${ID}`);
        return;
    }

    // 在删除前创建备份
    try {
        const backupDir = path.join(FILE_PATH['player'], GROUP_ID.toString(), 'backup');
        if (!fs.existsSync(backupDir)) {
            fs.mkdirSync(backupDir, { recursive: true });
        }
        const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
        const backupPath = path.join(backupDir, `${ID}_${timestamp}.json`);
        fs.copyFileSync(filePath, backupPath);

        // 记录删除原因和时间
        logger.info(`删除存档: 群${GROUP_ID} 用户${ID} 备份至 ${backupPath}`);

        return new Promise((resolve, reject) => {
            fs.unlink(filePath, (err) => {
                if (err) {
                    logger.error(`存档删除失败: 群${GROUP_ID} 用户${ID} 错误: ${err}`);
                    reject(err);
                    return;
                }
                resolve();
            });
        });
    } catch (err) {
        logger.error(`存档备份/删除过程出错: 群${GROUP_ID} 用户${ID} 错误: ${err}`);
        throw err;
    }
}

/** 读取群列表 */
export function getGroupList() {
    const files = fs.readdirSync(FILE_PATH['player']);
    return files.filter(file => /^\d+$/.test(file));
}

/** 检查并初始化群组和玩家 */
export async function ensureGroupAndPlayerExist(GROUP_ID, ID, nickname = '') {
    if (!isGroupExist(GROUP_ID)) {
        createAGroupFolder(GROUP_ID);
    }
    if (!isPlayerExist(GROUP_ID, ID)) {
        await storagePlayerData(GROUP_ID, ID, {
            currency: 0,
            slave: [],
            value: 100,
            lastWorkingTime: 0,
            master: '',
            nickname: nickname
        });
    } else if (nickname) {
        // 如果玩家已存在且提供了昵称，更新昵称
        const userData = JSON.parse(fs.readFileSync(path.join(FILE_PATH['player'], GROUP_ID.toString(), ID + '.json'), 'utf8'));
        await storagePlayerData(GROUP_ID, ID, userData, nickname);
    }
}

// 添加一个新的辅助函数来处理金币数值
export function formatCurrency(amount) {
    return parseFloat(amount.toFixed(2));
}

// 在文件末尾添加新函数
export function checkPermission(e) {
    const config = getConfig();
    // 检查用户ID是否在配置列表中
    if (config.ignoreCDUsers.includes(String(e.user_id))) {
        return true;
    }
    return false;
}

// 周数计算函数（ISO周）
export function getWeekNumber(date) {
    const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
    d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
    const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
    return Math.ceil(((d - yearStart) / 86400000 + 1) / 7);
}

// 获取每周重置的追踪文件路径
function getWeeklyResetTrackingPath() {
    return path.join(PLUGIN_PATH, 'data', 'weekly_reset_tracking.json');
}

// 读取每周重置追踪数据
export function getWeeklyResetTracking() {
    const trackingPath = getWeeklyResetTrackingPath();
    if (!fs.existsSync(trackingPath)) {
        return {
            lastResetWeek: 0,
            lastResetTime: 0,
            resetCount: 0
        };
    }
    try {
        return JSON.parse(fs.readFileSync(trackingPath, 'utf8'));
    } catch (e) {
        logger.error('每周重置追踪文件读取失败:', e);
        return {
            lastResetWeek: 0,
            lastResetTime: 0,
            resetCount: 0
        };
    }
}

// 保存每周重置追踪数据
export function saveWeeklyResetTracking(data) {
    const trackingPath = getWeeklyResetTrackingPath();
    const trackingDir = path.dirname(trackingPath);

    if (!fs.existsSync(trackingDir)) {
        fs.mkdirSync(trackingDir, { recursive: true });
    }

    try {
        fs.writeFileSync(trackingPath, JSON.stringify(data, null, 4));
    } catch (e) {
        logger.error('每周重置追踪文件保存失败:', e);
    }
}

// 检查是否需要进行每周重置
export function shouldPerformWeeklyReset() {
    const config = getConfig();
    if (!config.weeklyReset || !config.weeklyReset.enabled) {
        return false;
    }

    const currentDate = new Date();
    const currentWeek = getWeekNumber(currentDate);
    const tracking = getWeeklyResetTracking();

    // 如果是新的一周，检查是否到了重置时间
    if (currentWeek !== tracking.lastResetWeek) {
        const resetTime = config.weeklyReset.resetTime;
        const currentDay = currentDate.getDay(); // 0=周日, 1=周一, ..., 6=周六
        const currentHour = currentDate.getHours();
        const currentMinute = currentDate.getMinutes();

        // 检查是否到了指定的重置时间
        if (currentDay >= resetTime.day) {
            if (currentDay > resetTime.day ||
                (currentDay === resetTime.day && currentHour > resetTime.hour) ||
                (currentDay === resetTime.day && currentHour === resetTime.hour && currentMinute >= resetTime.minute)) {
                return true;
            }
        }
    }

    return false;
}



// 生成排行榜数据的通用函数
export async function generateRankingData(groupId, type = 'all') {
    try {
        const playerList = getGroupPlayerList(groupId);
        const rankings = [];
        let memberInfoList = {};

        try {
            memberInfoList = Object.fromEntries([...await Bot.pickGroup(groupId).getMemberMap()]);
        } catch (e) {
            logger.warn(`无法获取群${groupId}的成员列表:`, e);
        }

        for (const playerId of playerList) {
            try {
                // 跳过备份文件夹
                if (playerId === 'backup') continue;

                const qq = playerId.replace('.json', '');
                const playerData = await getPlayerData(groupId, qq);

                const nickname = playerData.nickname ||
                    memberInfoList[qq]?.card ||
                    memberInfoList[qq]?.nickname ||
                    `用户${qq}`;

                const rankingEntry = {
                    id: qq,
                    nickname: nickname,
                    currency: playerData.currency || 0,
                    value: playerData.value || 100,
                    slaveCount: (playerData.slave || []).length,
                    master: playerData.master || '',
                    weeklyResets: playerData.weeklyResets || 0,
                    bankLevel: playerData.bankLevel || 1,
                    bankBalance: playerData.bankBalance || 0,
                    tier: playerData.tier || '青铜',
                    rankingWins: playerData.rankingWins || 0,
                    rankingLosses: playerData.rankingLosses || 0
                };

                rankings.push(rankingEntry);
            } catch (err) {
                logger.error(`处理玩家数据时出错 [群:${groupId}, QQ:${playerId}]:`, err);
                continue;
            }
        }

        // 根据类型返回不同的排行榜
        const result = {
            groupId: groupId,
            timestamp: Math.floor(Date.now() / 1000),
            playerCount: rankings.length
        };

        if (type === 'all' || type === 'currency') {
            result.currencyRanking = [...rankings]
                .sort((a, b) => b.currency - a.currency)
                .slice(0, 15)
                .map((player, index) => ({
                    rank: index + 1,
                    ...player
                }));
        }

        if (type === 'all' || type === 'value') {
            result.valueRanking = [...rankings]
                .sort((a, b) => b.value - a.value)
                .slice(0, 15)
                .map((player, index) => ({
                    rank: index + 1,
                    ...player
                }));
        }

        if (type === 'all' || type === 'slave') {
            result.slaveRanking = [...rankings]
                .sort((a, b) => b.slaveCount - a.slaveCount)
                .slice(0, 15)
                .map((player, index) => ({
                    rank: index + 1,
                    ...player
                }));
        }

        if (type === 'all' || type === 'bank') {
            result.bankRanking = [...rankings]
                .sort((a, b) => {
                    if (b.bankLevel !== a.bankLevel) return b.bankLevel - a.bankLevel;
                    return b.bankBalance - a.bankBalance;
                })
                .slice(0, 15)
                .map((player, index) => ({
                    rank: index + 1,
                    ...player
                }));
        }

        return result;
    } catch (error) {
        logger.error(`生成排行榜数据时出错 [群:${groupId}]:`, error);
        return null;
    }
}

// 保存每周排行榜历史数据
export function saveWeeklyRankingHistory(groupId, rankingData) {
    try {
        const historyDir = path.join(PLUGIN_PATH, 'data', 'ranking_history');
        if (!fs.existsSync(historyDir)) {
            fs.mkdirSync(historyDir, { recursive: true });
        }

        const currentDate = new Date();
        const week = getWeekNumber(currentDate);
        const year = currentDate.getFullYear();

        const filename = `${groupId}_${year}_week${week}.json`;
        const filepath = path.join(historyDir, filename);

        const historyData = {
            ...rankingData,
            week: week,
            year: year,
            weeklyResetTime: Math.floor(Date.now() / 1000)
        };

        fs.writeFileSync(filepath, JSON.stringify(historyData, null, 4));
        logger.info(`已保存群${groupId}第${week}周排行榜历史数据`);
        return filepath;
    } catch (error) {
        logger.error(`保存排行榜历史数据失败 [群:${groupId}]:`, error);
        return null;
    }
}

// 获取上周排行榜数据
export function getLastWeekRankingHistory(groupId) {
    try {
        const historyDir = path.join(PLUGIN_PATH, 'data', 'ranking_history');
        if (!fs.existsSync(historyDir)) {
            return null;
        }

        const currentDate = new Date();
        const currentWeek = getWeekNumber(currentDate);
        const currentYear = currentDate.getFullYear();

        // 计算上周
        let lastWeek = currentWeek - 1;
        let lastYear = currentYear;

        if (lastWeek < 1) {
            lastYear = currentYear - 1;
            lastWeek = getWeekNumber(new Date(lastYear, 11, 31)); // 去年最后一周
        }

        const filename = `${groupId}_${lastYear}_week${lastWeek}.json`;
        const filepath = path.join(historyDir, filename);

        if (!fs.existsSync(filepath)) {
            return null;
        }

        return JSON.parse(fs.readFileSync(filepath, 'utf8'));
    } catch (error) {
        logger.error(`读取上周排行榜数据失败 [群:${groupId}]:`, error);
        return null;
    }
}

// 格式化排行榜消息
export function formatRankingMessage(rankingData, title) {
    if (!rankingData || rankingData.length === 0) {
        return [`${title}：暂无数据`];
    }

    const message = [`🏆 ${title}\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`];

    rankingData.forEach((player, index) => {
        const rankIcon = index === 0 ? '🥇' : index === 1 ? '🥈' : index === 2 ? '🥉' : `${player.rank}.`;
        const nickname = player.nickname.length > 8 ? player.nickname.substring(0, 8) + '...' : player.nickname;

        if (title.includes('金币')) {
            message.push(`${rankIcon} ${nickname} - ${player.currency}💰`);
        } else if (title.includes('身价')) {
            message.push(`${rankIcon} ${nickname} - ${player.value}💎`);
        } else if (title.includes('奴隶')) {
            message.push(`${rankIcon} ${nickname} - ${player.slaveCount}个奴隶`);
        } else if (title.includes('银行')) {
            message.push(`${rankIcon} ${nickname} - Lv.${player.bankLevel} (${player.bankBalance}💰)`);
        }
    });

    return message;
}

// 修改后的执行每周重置函数
export async function performWeeklyReset() {
    try {
        const config = getConfig();
        if (!config.weeklyReset || !config.weeklyReset.enabled) {
            logger.info('每周重置功能未启用');
            return { success: false, message: '每周重置功能未启用' };
        }

        const currentDate = new Date();
        const currentWeek = getWeekNumber(currentDate);
        const currentTime = Math.floor(Date.now() / 1000);

        let resetCount = 0;
        let errorCount = 0;
        const weeklyRankings = {};

        logger.info('开始执行每周重置...');

        // 获取所有群组
        const groupList = getGroupList();

        // 第一步：为每个群组生成并保存排行榜数据
        for (const groupId of groupList) {
            try {
                logger.info(`正在为群${groupId}生成排行榜数据...`);
                const rankingData = await generateRankingData(groupId, 'all');
                if (rankingData) {
                    const historyPath = saveWeeklyRankingHistory(groupId, rankingData);
                    if (historyPath) {
                        weeklyRankings[groupId] = rankingData;
                    }
                }
            } catch (error) {
                logger.error(`生成群${groupId}排行榜数据失败:`, error);
            }
        }

        // 第二步：重置所有玩家数据
        for (const groupId of groupList) {
            try {
                // 获取群组内所有玩家
                const playerList = getGroupPlayerList(groupId);

                for (const playerFile of playerList) {
                    // 跳过备份文件夹
                    if (playerFile === 'backup') continue;

                    const playerId = playerFile.replace('.json', '');

                    try {
                        // 读取玩家数据
                        const playerData = await getPlayerData(groupId, playerId);

                        // 备份原始数据
                        const backupDir = path.join(FILE_PATH['player'], groupId, 'backup');
                        if (!fs.existsSync(backupDir)) {
                            fs.mkdirSync(backupDir, { recursive: true });
                        }

                        const timestamp = currentDate.toISOString().replace(/[:.]/g, '-');
                        const backupPath = path.join(backupDir, `${playerId}_weekly_reset_${timestamp}.json`);
                        fs.writeFileSync(backupPath, JSON.stringify(playerData, null, 4));

                        // 创建重置后的数据
                        const resetData = {
                            currency: 0,                    // 重置金币
                            slave: [],                      // 清空奴隶列表
                            value: config.weeklyReset.preserveData.basicValue || 100,  // 重置身价
                            lastWorkingTime: 0,             // 重置工作时间
                            master: '',                     // 清空主人
                            nickname: config.weeklyReset.preserveData.nickname ?
                                (playerData.nickname || '') : '',  // 根据配置决定是否保留昵称

                            // 重置所有计数器和时间戳
                            buyBackTimes: 0,
                            lastBuyBackTime: 0,

                            // 重置银行数据
                            bankLevel: 1,
                            bankLimit: config.bank.initialLimit || 1000,
                            bankBalance: 0,
                            lastInterestTime: 0,

                            // 重置训练数据
                            lastTrainingTime: 0,

                            // 重置竞技数据
                            lastArenaTime: 0,

                            // 重置排位赛数据
                            lastRankingTime: 0,
                            tier: '青铜',
                            rankingWins: 0,
                            rankingLosses: 0,

                            // 重置抢劫数据
                            lastRobTime: 0,

                            // 重置购买数据
                            lastPurchaseTime: 0,

                            // 添加重置记录
                            weeklyResets: (playerData.weeklyResets || 0) + 1,
                            lastResetTime: currentTime,
                            lastResetWeek: currentWeek
                        };

                        // 保存重置后的数据
                        storagePlayerData(groupId, playerId, resetData);
                        resetCount++;

                    } catch (playerError) {
                        logger.error(`重置玩家数据失败: 群${groupId} 用户${playerId}`, playerError);
                        errorCount++;
                    }
                }

            } catch (groupError) {
                logger.error(`处理群组失败: ${groupId}`, groupError);
                errorCount++;
            }
        }

        // 更新重置追踪数据
        const tracking = getWeeklyResetTracking();
        tracking.lastResetWeek = currentWeek;
        tracking.lastResetTime = currentTime;
        tracking.resetCount = (tracking.resetCount || 0) + 1;
        saveWeeklyResetTracking(tracking);

        logger.info(`每周重置完成: 重置了${resetCount}个玩家数据，失败${errorCount}个`);

        return {
            success: true,
            message: `每周重置完成: 重置了${resetCount}个玩家数据，失败${errorCount}个`,
            resetCount,
            errorCount,
            resetTime: currentTime,
            weeklyRankings: weeklyRankings  // 包含所有群组的排行榜数据
        };

    } catch (error) {
        logger.error('每周重置过程中发生错误:', error);
        return {
            success: false,
            message: `每周重置失败: ${error.message}`,
            error: error.message
        };
    }
}

// 自动检查并执行每周重置（在其他函数调用时检查）
export async function checkAndPerformWeeklyReset() {
    if (shouldPerformWeeklyReset()) {
        logger.info('检测到需要进行每周重置');
        return await performWeeklyReset();
    }
    return null;
}